package com.smartsystem.modules.system.controller;

import com.smartsystem.common.controller.BaseController;
import com.smartsystem.common.service.TokenBlacklistService;
import com.smartsystem.common.utils.JWTUtils;
import com.smartsystem.common.utils.PasswordUtils;
import com.smartsystem.common.utils.Result;
import com.smartsystem.common.utils.UserContext;
import com.smartsystem.modules.system.dto.LoginDTO;
import com.smartsystem.modules.system.dto.RegisterDTO;
import com.smartsystem.modules.system.entity.SysUser;
import com.smartsystem.modules.system.service.SysUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 认证控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/auth")
@Tag(name = "用户认证", description = "🔐 用户登录、注册、权限验证等认证相关接口")
@Validated
public class AuthController extends BaseController {
    
    @Resource
    private SysUserService sysUserService;
    
    /**
     * 用户登录
     * @param loginDTO 登录信息
     * @return 登录结果
     */
    @PostMapping("/login")
    @Operation(summary = "用户登录", description = "用户通过用户名和密码进行登录认证")
    public Result<Map<String, Object>> login(
            @Parameter(description = "登录信息", required = true)
            @RequestBody @Valid LoginDTO loginDTO) {
        
        // 使用validateUser方法验证用户
        SysUser user = sysUserService.validateUser(loginDTO.getUsername(), loginDTO.getPassword());
        
        // 生成JWT令牌
        String token = JWTUtils.generateToken(user.getUsername(), user.getId());
        
        // 构建返回数据
        Map<String, Object> data = new HashMap<>();
        data.put("token", token);
        data.put("tokenType", "Bearer");
        data.put("expiresIn", 7200); // 2小时
        
        // 用户信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("realName", user.getRealName());
        userInfo.put("avatar", user.getAvatar());
        // TODO: 从数据库获取用户角色和权限
        userInfo.put("roles", new String[]{"SUPER_ADMIN"});
        userInfo.put("permissions", new String[]{"*:*:*"});
        data.put("userInfo", userInfo);
        
        return Result.success(data, "登录成功");
    }
    
    @Resource
    private TokenBlacklistService tokenBlacklistService;
    
    /**
     * 用户登出
     * @return 登出结果
     */
    @PostMapping("/logout")
    @Operation(summary = "用户登出", description = "用户登出系统，清除认证信息")
    public Result<String> logout() {
        try {
            // 获取当前Token
            String token = UserContext.getTokenFromRequest();
            if (token != null) {
                // 将token加入黑名单
                tokenBlacklistService.addToBlacklist(token);
            }
            
            // TODO: 清除Redis中的用户会话信息
            // TODO: 记录登出日志
            
            return Result.success("登出成功");
        } catch (Exception e) {
            log.error("用户登出失败", e);
            return Result.fail("登出失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户信息
     * @return 用户信息
     */
    @GetMapping("/userinfo")
    @Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息")
    public Result<Map<String, Object>> getUserInfo() {
        // 从JWT token中获取用户信息
        Long userId = UserContext.getCurrentUserId();
        if (userId == null) {
            return Result.fail(401, "未登录或Token已过期");
        }
        
        // 获取用户详细信息
        SysUser user = sysUserService.getById(userId);
        if (user == null) {
            return Result.fail(404, "用户不存在");
        }
        
        // 构建用户信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("id", user.getId());
        userInfo.put("username", user.getUsername());
        userInfo.put("realName", user.getRealName());
        userInfo.put("avatar", user.getAvatar());
        userInfo.put("phone", user.getPhone());
        userInfo.put("email", user.getEmail());
        userInfo.put("department", user.getDepartment());
        userInfo.put("position", user.getPosition());
        userInfo.put("status", user.getStatus());
        
        // 获取用户角色
        List<Long> roleIds = sysUserService.getUserRoles(userId);
        // TODO: 根据角色ID获取角色名称和权限，这里先返回基础信息
        userInfo.put("roleIds", roleIds);
        userInfo.put("roles", new String[]{"USER"}); // 临时数据
        userInfo.put("permissions", new String[]{"system:user:view"}); // 临时数据
        
        return Result.success(userInfo);
    }
    

    
    /**
     * 修改密码
     * @param passwordMap 密码信息
     * @return 修改结果
     */
    @PostMapping("/change-password")
    @Operation(summary = "修改密码", description = "用户修改自己的登录密码")
    public Result<String> changePassword(
            @Parameter(description = "密码信息", required = true)
            @RequestBody Map<String, String> passwordMap) {
        
        String oldPassword = passwordMap.get("oldPassword");
        String newPassword = passwordMap.get("newPassword");
        String confirmPassword = passwordMap.get("confirmPassword");
        
        // 参数验证
        if (oldPassword == null || oldPassword.trim().isEmpty()) {
            return Result.fail("原密码不能为空");
        }
        if (newPassword == null || newPassword.trim().isEmpty()) {
            return Result.fail("新密码不能为空");
        }
        if (newPassword.length() < 6 || newPassword.length() > 20) {
            return Result.fail("新密码长度必须在6-20个字符之间");
        }
        if (!newPassword.equals(confirmPassword)) {
            return Result.fail("两次输入的密码不一致");
        }
        if (oldPassword.equals(newPassword)) {
            return Result.fail("新密码不能与原密码相同");
        }
        
        // 从JWT中获取当前用户ID
        Long userId = UserContext.getCurrentUserId();
        if (userId == null) {
            return Result.fail(401, "未登录或Token已过期");
        }
        
        try {
            // 获取当前用户信息
            SysUser user = sysUserService.getById(userId);
            if (user == null) {
                return Result.fail(404, "用户不存在");
            }
            
            // 验证原密码是否正确
            if (!PasswordUtils.matches(oldPassword, user.getPassword())) {
                return Result.fail("原密码错误");
            }
            
            // 更新新密码
            user.setPassword(PasswordUtils.encodePassword(newPassword));
            boolean success = sysUserService.updateById(user);
            
            if (success) {
                // TODO: 记录操作日志
                return Result.success("密码修改成功，请重新登录");
            } else {
                return Result.fail("密码修改失败，请稍后重试");
            }
            
        } catch (Exception e) {
            log.error("修改密码失败", e);
            return Result.fail("密码修改失败：" + e.getMessage());
        }
    }
    
    /**
     * 用户注册
     * @param registerDTO 注册信息
     * @return 注册结果
     */
    @PostMapping("/register")
    @Operation(summary = "用户注册", description = "新用户注册账号")
    public Result<Map<String, Object>> register(
            @Parameter(description = "注册信息", required = true)
            @RequestBody @Valid RegisterDTO registerDTO) {
        
        // 验证两次密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getConfirmPassword())) {
            return Result.fail("两次输入的密码不一致");
        }
        
        // 检查用户名是否已存在
        if (sysUserService.checkUsernameExists(registerDTO.getUsername(), null)) {
            return Result.fail("用户名已存在");
        }
        
        // 检查手机号是否已存在
        if (sysUserService.checkPhoneExists(registerDTO.getPhone(), null)) {
            return Result.fail("手机号已被注册");
        }
        
        // 检查邮箱是否已存在（如果提供了邮箱）
        if (registerDTO.getEmail() != null && !registerDTO.getEmail().trim().isEmpty()) {
            if (sysUserService.checkEmailExists(registerDTO.getEmail(), null)) {
                return Result.fail("邮箱已被注册");
            }
        }
        
        try {
            // 创建用户对象
            SysUser user = new SysUser();
            user.setUsername(registerDTO.getUsername());
            user.setPassword(PasswordUtils.encodePassword(registerDTO.getPassword()));
            user.setRealName(registerDTO.getRealName());
            user.setGender(registerDTO.getGender());
            user.setPhone(registerDTO.getPhone());
            user.setEmail(registerDTO.getEmail());
            user.setDepartment(registerDTO.getDepartment());
            user.setPosition(registerDTO.getPosition());
            user.setStatus(1); // 默认启用状态
            // createTime和updateTime由MyBatis-Plus自动填充，不需要手动设置
            
            // 保存用户信息
            boolean success = sysUserService.save(user);
            
            if (success) {
                // TODO: 分配默认角色（普通用户角色）
                // TODO: 记录注册日志
                
                Map<String, Object> result = new HashMap<>();
                result.put("userId", user.getId());
                result.put("username", user.getUsername());
                result.put("realName", user.getRealName());
                result.put("message", "注册成功，可以立即登录使用");
                
                return Result.success(result, "用户注册成功");
            } else {
                return Result.fail("用户注册失败，请稍后重试");
            }
            
        } catch (Exception e) {
            log.error("用户注册失败", e);
            return Result.fail("用户注册失败：" + e.getMessage());
        }
    }
}